package com.asp.aspchain.transaction.service;

import com.asp.aspchain.core.ethereum.EthService;
import com.asp.aspchain.transaction.disruptor.*;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.YieldingWaitStrategy;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.EthBlock;
import rx.Subscription;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Component
public class ListenService {
	private final static Logger logger = Logger.getLogger(ListenService.class);
	@Autowired
	EthService ethService;
	@Autowired
	ListenDataIntoDBHandler listenDataIntoDBHandler;
	@Autowired
	ListenDataIntoPublishHandler listenDataIntoPublishHandler;
	@PostConstruct
	public void listen() {

		EventFactory<ListenDataEvent> eventFactory = new ListenDataEventFactory();
		ExecutorService executor = Executors.newFixedThreadPool(4);
		int ringBufferSize = 1024 * 1024; // RingBuffer 大小，必须是 2 的 N 次方；

		Disruptor<ListenDataEvent> disruptor = new Disruptor<ListenDataEvent>(eventFactory,
				ringBufferSize, executor, ProducerType.SINGLE,
				new YieldingWaitStrategy());

		disruptor.handleEventsWith(listenDataIntoDBHandler).then(listenDataIntoPublishHandler);

		disruptor.start();

		Web3j web3j = ethService.initWeb3j();

		Subscription subscription = web3j.blockObservable(false).subscribe(block -> {
			EthBlock.Block blk = block.getResult();
			RingBuffer<ListenDataEvent> ringBuffer = disruptor.getRingBuffer();
			ringBuffer.publishEvent(new ListenEventTranslator(), blk);
			long threadId = Thread.currentThread().getId();
			logger.info("生产者ThreadId: " + threadId + "，BlockNum：" + blk.getNumber() + "，BlockHash: " + blk.getHash());
		});
		logger.info("订阅的" + subscription.hashCode());
	}




	public static void main(String[] args) throws IOException {
		/*BigInteger nonce = new BigInteger("6758");
		BigInteger gasPrice = BigInteger.valueOf(22_000_000_000L);
		BigInteger gasLimit = BigInteger.valueOf(4_300_000);
		BigInteger value = new BigInteger("1000000000000000000");
		Transaction createEtherTransaction = Transaction.createEtherTransaction("0x1e5f0d70417defa2d5d41b7dc6c8f594e377454f", nonce, gasPrice, gasLimit, "0x7f9e28a421ad5dd04a52326e4e5863d41a577010", value);
		String hash = EthServicetest.sendTransaction(createEtherTransaction, "123456");
		System.out.println(hash);*/
		/*Web3j web3j = EthServicetest.initWeb3j();
		Subscription subscription = web3j.blockObservable(false).subscribe(block -> {
			EthBlock.Block blk = block.getResult();
			logger.info("当前区块高度：" + blk.getNumber() + "当前区块hash" + blk.getHash());
		});
		logger.info("订阅的" + subscription.hashCode());*/
		/*byte[] bytes = "abc".getBytes();

		System.out.println(bytes.toString());
		BigInteger bigInteger = new BigInteger(1, bytes);
		System.out.println(bigInteger);
		BigInteger integer =  BigInteger.valueOf(6382179);
		byte[] bytes1 = integer.toByteArray();
		System.out.println(new String(bytes1));

		String privateKey = "86890411808909332432221682524931332103291749589896917805592424968759646313056";
		System.out.println(String.format("%040x", new BigInteger(1, bytes)));*/

	}
}
